/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

export function addEventListener (node, event, listener) {
    if (node.addEventListener) {
        node.addEventListener(event, listener, false)
    } else {
        node.attachEvent(`on${event}`, listener)
    }
}

export function removeEventListener (node, event, listener) {
    if (node.removeEventListener) {
        node.removeEventListener(event, listener, false)
    } else {
        node.detachEvent(`on${event}`, listener)
    }
}

export function windowScrollX () {
    return (window.pageXOffset !== undefined) ? window.pageXOffset :
        (document.documentElement || document.body.parentNode || document.body).scrollLeft
}

export function windowScrollY () {
    return (window.pageYOffset !== undefined) ? window.pageYOffset :
        (document.documentElement || document.body.parentNode || document.body).scrollTop
}

/**
 * 遍历一个元素的父节点，直至该节点含有相应的classname
 * @param node
 * @param classname
 * @return dom | null
 */
export function getParentNode (node, classname) {
    let parentNode = node.parentNode
    let resultNode = null
    while (parentNode !== null) {
        if (parentNode.classList && parentNode.classList.contains(classname)) {
            resultNode = parentNode
            break
        } else {
            parentNode = parentNode.parentNode
        }
    }
    return resultNode
}

/**
 *
 * @param 返回被@withStyle, @connect包裹的component
 */
export function getRealComponent (component) {
    function getReal (wrapComponent) {
        let com = null
        if (!wrapComponent) {
            return null
        }
        if (wrapComponent.getWrappedInstance) {
            com = wrapComponent.getWrappedInstance()
        } else if (wrapComponent.getComposedInstance) {
            com = wrapComponent.getComposedInstance()
        } else {
            com = wrapComponent
        }
        return com
    }

    // 嵌套两层，防止@connect @withStyle位置互换的问题
    return getReal(getReal(component))
}


export function getRootFontSize () {
    let rootFontSize = 15
    if (document && window.getComputedStyle) {
        rootFontSize = parseInt(window.getComputedStyle(document.body).fontSize, 10)
    }
    return rootFontSize
}

/**
 * 异步加载脚本，返回promise代表该脚本是否加载成功
 * @param scriptId
 * @param src
 * @return {*}
 */
export function asyncLoadScript (scriptId, src) {
    if (!process.env.BROWSER) {
        throw new Error('非浏览器环境不能调用asyncLoadScript函数')
    }
    if (!window.ASYNC_SCRIPTS) {
        window.ASYNC_SCRIPTS = {}
    }
    if (!window.ASYNC_SCRIPTS[scriptId]) {
        window.ASYNC_SCRIPTS[scriptId] = new Promise((resolve, reject) => {
            const scriptNode = document.createElement('script')
            scriptNode.src = src
            scriptNode.onload = () => {
                resolve()
            }
            scriptNode.onerror = () => {
                console.log(`致命错误，加载脚本${scriptId}:${src}失败`)
                reject()
            }
            document.body.appendChild(scriptNode)
        })
    }

    return window.ASYNC_SCRIPTS[scriptId]
}

export function getClassList (element) {
    return (element && element.getAttribute('class') || '').split(' ')
}

export function containsClass (element, className) {
    return (element && element.getAttribute('class') || '').indexOf(className) >= 0
}

/**
 * dom node toggle Class
 * @param element
 * @param className
 * @param forceAddOrRemove  true => force add; false => force remove; undefined => toggle
 */
export function toggleClass (element, className, forceAddOrRemove) {
    if (!element || !className) {
        return
    }

    const doAdd = (forceAddOrRemove === undefined) ? !containsClass(element, className) : !!forceAddOrRemove

    if (doAdd) { // add
        element.setAttribute('class', `${element.getAttribute('class')} ${className}`)
    } else { // remove
        const classString = element.getAttribute('class')
        const nameIndex = classString.indexOf(className)
        if (nameIndex !== -1) {
            element.setAttribute('class', classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length))
        }
    }
}

export function addClass (element, className) {
    toggleClass(element, className, true)
}

export function removeClass (element, className) {
    toggleClass(element, className, false)
}
